class EventObject {

  constructor(event, desc) {
    this.event = event
    this.desc = desc
  }
}

class Node {
  constructor(value, desc) {
    this.eventObj = new EventObject(value, desc) //节点的数据域
    this.pre = null    //前驱指针域
    this.next = null   //后继指针域
  }
}

class EventListenter {
  constructor(type, event, desc) {
    this.type = type                    // 事件类型
    if(event) {
      this.tail = new Node(event, desc)     //链表的尾结点
      this.size = 1                    // 链表的长度
    } else {
      this.tail = new Node(() => {}, 'null')     //链表的尾结点
      this.size = 0                    // 链表的长度
    }
  }

  findN(n) {
    // 获取链表的第n个节点
    let currnode = this.tail
    if(this.tail) {
      while((this.size - (n++)) && currnode.pre) {
        currnode = currnode.pre
      }
      return currnode
    } else {
      return '暂无事件'
    }
  }

  /**
   * 插入节点
   * @param callback 回调
   * @param num 位置
   * @param desc 事件描述
   */
  append(callback, num, desc) {
    let currnode
    let newnode = new Node(callback, desc) //新节点
    if(num === undefined || this.size === num) {
      currnode = this.findN(this.size)
      // 在链表尾部添加元素
      newnode.pre = currnode
      this.tail = newnode
    } else {
      currnode = this.findN(num)
      // 中间插入节点
      newnode.pre = currnode.pre
      currnode.pre = newnode
    }
    this.size++
  }

  find(desc) {
    // 寻找事件描述为desc的节点
    let currnode = this.tail

    while(currnode && currnode.eventObj.desc !== desc) {
      currnode = currnode.pre
    }
    return currnode
  }

  // insert(item, element) {
  //   // 在item元素后面插入值为element的新节点
  //
  //   let currnode = this.find(item)
  //   // 如果item不存在
  //   if(!currnode) {
  //     return
  //   }
  //   let newnode = new Node(element)
  //   newnode.next = currnode.next
  //   currnode.next = newnode
  //
  //   this.size++
  // }

  /**
   * 移除某个回调
   * @param desc 事件描述
   */
  remove(desc) {
    // 在链表中删除值为item的节点
    let n = this.checkN(desc)
    if(n === this.size) {
      // 删最后一个
      this.tail = this.tail.pre
      this.size--
      return
    }
    let pre = this.findN(n + 1)
    // pre.pre = pre.pre.pre
    let cur = this.findN(n)
    pre.pre = cur.pre
    this.size--
  }

  checkN(desc) {
    // 查找值为item的节点是第几个
    let currnode = this.find(desc)
    if(!currnode) {
      return -1
    }
    let res = this.tail
    let count = this.size
    while(res && res.eventObj.desc !== currnode.eventObj.desc) {
      res = res.pre
      count--
    }
    return count
  }

  isEmpty() {
    // 判断链表是否为空
    return this.size === 0
  }

  getLength() {
    // 获取链表的长度
    return this.size
  }

  clear() {
    // 清空链表
    this.tail = null
    this.size = 0
  }

  start() {
    //  开始监听
    let count = this.size
    let event = this.tail
    let arrEvent = []
    while(count) {
      // 当前事件压入待执行栈
      arrEvent.unshift(event.eventObj.event)
      event = event.pre
      --count
    }
    for(let i of arrEvent) {
      i()
    }
  }
}

//以下测试用
// const SL = new EventListenter('Left-click', () => {
//   console.log(111)
// }, '打印111')
//
// SL.append(() => {
//   console.log(222)
// }, undefined, '打印222')
//
// SL.append(() => {
//   console.log(333)
// }, undefined, '打印333')
//
// SL.append(() => {
//   console.log(444)
// }, undefined, '打印444')
// SL.append(() => {
//   console.log(7877)
// }, 3, '打印7877')
//
// SL.append(() => {
//   console.log(555)
// }, undefined, '打印555')
//
// // SL.remove('打印333')
// SL.start()
// console.log(SL, 'Left-click----------')
// SL.clear()
// SL.append(() => {
//   console.log(555)
// }, undefined, '打印555')
// SL.start()
// console.log(SL, 'Left-click----console.log(SL, \'Left-click----------\')\n------')
